package com.spring.boot.core.utils;

public class ByteUtils {

	/**
	 *  size
	 */

	public static int sizeOfBool(boolean input) {
		return 1;
	}

	public static int sizeOfShort(int input) {
		return 2;
	}
	
	public static int sizeOfInt(int input) {
		return 4;
	}

	public static int sizeOfLong(long input) {
		return 8;
	}

	public static int sizeOfFloat(float input) {
		return 4;
	}

	public static int sizeOfDouble(double input) {
		return 8;
	}

	public static int sizeOfString(String input) {
		return 4 + input.getBytes().length;
	}

	/**
	 *  write
	 */

	public static int writeBool(byte[] output, int offset, boolean input) {
		output[offset] = (byte) (input ? 0 : 1);
		return 1;
	}

	public static int writeByte(byte[] output, int offset, byte input) {
		output[offset] = input;
		return 1;
	}
	
	public static int writeShort(byte[] output, int offset, int input) {
		output[offset  ] = (byte)((input      ) & 0xff);
		output[offset+1] = (byte)((input >>  8) & 0xff);
		return 2;
	}

	public static int writeInt(byte[] output, int offset, int input) {
		output[offset  ] = (byte)((input      ) & 0xff);
		output[offset+1] = (byte)((input >>  8) & 0xff);
		output[offset+2] = (byte)((input >> 16) & 0xff);
		output[offset+3] = (byte)((input >> 24) & 0xff);
		return 4;
	}

	public static int writeLong(byte[] output, int offset, long input) {
		output[offset  ] = (byte)((input      ) & 0xff);
		output[offset+1] = (byte)((input >>  8) & 0xff);
		output[offset+2] = (byte)((input >> 16) & 0xff);
		output[offset+3] = (byte)((input >> 24) & 0xff);
		output[offset+4] = (byte)((input >> 32) & 0xff);
		output[offset+5] = (byte)((input >> 40) & 0xff);
		output[offset+6] = (byte)((input >> 48) & 0xff);
		output[offset+7] = (byte)((input >> 56) & 0xff);
		return 8;
	}

	public static int writeFloat(byte[] output, int offset, float input) {
		return writeInt(output, offset, Float.floatToRawIntBits(input));
	}

	public static int writeDouble(byte[] output, int offset, double input) {
		return writeLong(output, offset, Double.doubleToRawLongBits(input));
	}

	public static int writeString(byte[] output, int offset, String input) {
		writeInt(output, offset, input.length());
		offset += 4;
		byte[] value = input.getBytes();
		for (int i = 0; i < value.length; i ++) {
			output[offset+i] = value[i];
		}
		return 4 + value.length;
	}
	
	/**
	 *  read
	 */

	 public static boolean readBool(byte[] input, int offset) {
		 return input[offset] != 0;
	 }

	 public static byte readByte(byte[] input, int offset) {
		 return input[offset];
	 }
	 
	 public static int readShort(byte[] input, int offset) {
		 return  (((int)input[offset    ] & 0xff)      ) |
				 (((int)input[offset + 1] & 0xff) <<  8);
	 }

	 public static int readInt(byte[] input, int offset) {
		 return  (((int)input[offset    ] & 0xff)      ) |
				 (((int)input[offset + 1] & 0xff) <<  8) |
				 (((int)input[offset + 2] & 0xff) << 16) |
				 (((int)input[offset + 3] & 0xff) << 24) ;
	 }

	 public static long readLong(byte[] input, int offset) {
		 return  (((long)input[offset]     & 0xff)      ) |
				 (((long)input[offset + 1] & 0xff) <<  8) |
				 (((long)input[offset + 2] & 0xff) << 16) |
				 (((long)input[offset + 3] & 0xff) << 24) |
				 (((long)input[offset + 4] & 0xff) << 32) |
				 (((long)input[offset + 5] & 0xff) << 40) |
				 (((long)input[offset + 6] & 0xff) << 48) |
				 (((long)input[offset + 7] & 0xff) << 56) ;
	 }

	 public static float readFloat(byte[] input, int offset) {
		 return Float.intBitsToFloat(readInt(input, offset));
	 }

	 public static double readDouble(byte[] input, int offset) {
		 return Double.longBitsToDouble(readLong(input, offset));
	 }

	 public static String readString(byte[] input, int offset) {
		 int length = readInt(input, offset);
		 return new String(input, offset + 4, length);
	 }
}